﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using GLWrap.SceneObjects;
using ReAnimation.Domain;
using Sharp3D.Math.Core;
using GLWrap.MathExt;

namespace ReAnimation.Graphics.Handlers
{
    public class MoleculeTransformHandler: BaseHandler, IMoleculeTransformHandler
    {
        private bool  _rotatingMode;
        private bool _translateMode;
        private Point _initialPosition;
        private Point _lastPosition;
        private Vector3F _selectedAtomPosition;
        private Matrix4F _initialTransformMatrix;

        public MoleculeTransformHandler():base(null)
        {
            _rotatingMode = false;
    
        }

        protected override void PhysicallyStartHandle()
        {
 
            MoleculeDrawer.GlSceneManager.SceneMouseDown += GlSceneManager_SceneMouseDown;
            MoleculeDrawer.GlSceneManager.SceneMouseUp += GlSceneManager_SceneMouseUp;
            MoleculeDrawer.GlSceneManager.SceneMouseMove += GlSceneManager_SceneMouseMove;
        }

        void GlSceneManager_SceneMouseMove(object sender, ReAnimation.Helpers.WinForms.EventArg<Point> e)
        {
            Vector3F up = MoleculeDrawer.GlSceneManager.Camera.Up;
            Vector3F right = Vector3F.CrossProduct(MoleculeDrawer.GlSceneManager.Camera.View - MoleculeDrawer.GlSceneManager.Camera.Eye, MoleculeDrawer.GlSceneManager.Camera.Up);
        
            right.Normalize();
            up.Normalize();

            if (_rotatingMode)
            {
                
                Matrix4F rotMat = Matrix4FExtension.RotationMatrix((_initialPosition.X-e.Data.X)/-2, up);
                Matrix4F rotMat2 = Matrix4FExtension.RotationMatrix((_initialPosition.Y - e.Data.Y) / -2, right);
                Matrix4F translateMat = Matrix4FExtension.TranslateMatrix(_selectedAtomPosition);
                Matrix4F translateMat2 = Matrix4FExtension.TranslateMatrix(-_selectedAtomPosition);

                MoleculeDrawer.Molecule.TransformMatrix = translateMat * rotMat2 * rotMat * translateMat2 * _initialTransformMatrix;
               // MoleculeDrawer.MoleculeSceneObject.TransformationMatrix = MoleculeDrawer.Molecule.TransformMatrix;

                MoleculeDrawer.GlSceneManager.Refresh();
            }
            if (_translateMode)
            {
                Vector3F xv = right * (_initialPosition.X - e.Data.X) / -120;
                Vector3F yv = up * (_initialPosition.Y - e.Data.Y) / 120;

                Matrix4F translateMat = Matrix4FExtension.TranslateMatrix(xv + yv);

                MoleculeDrawer.Molecule.TransformMatrix = translateMat * _initialTransformMatrix;
              //  MoleculeDrawer.MoleculeSceneObject.TransformationMatrix = MoleculeDrawer.Molecule.TransformMatrix;

                MoleculeDrawer.GlSceneManager.Refresh();
            }

            
        }

        void GlSceneManager_SceneMouseUp(object sender, ReAnimation.Helpers.WinForms.EventArg<Point> e)
        {
            _rotatingMode = false;
            _translateMode = false;
        }

        void GlSceneManager_SceneMouseDown(object sender, ReAnimation.Helpers.WinForms.EventArg<Point> e)
        {
            SceneObject sceneObject = MoleculeDrawer.GlSceneManager.GetObjectAtPoint(e.Data);
            
            
            
            _initialPosition = e.Data;
            _initialTransformMatrix = MoleculeDrawer.Molecule.TransformMatrix;

            if (sceneObject == null || !MoleculeDrawer.SceneToAtomMap.ContainsKey(sceneObject))
            {
                _translateMode = true;
                
            }
            else
            {
                
                _rotatingMode = true;

                Sphere atom = (Sphere)sceneObject;
                
                _selectedAtomPosition = _initialTransformMatrix.Multiply(atom.Position);
            }
        }

        protected override void PhysicallyStopHandle()
        {
            MoleculeDrawer.GlSceneManager.SceneMouseDown -= GlSceneManager_SceneMouseDown;
            MoleculeDrawer.GlSceneManager.SceneMouseUp -= GlSceneManager_SceneMouseUp;
            MoleculeDrawer.GlSceneManager.SceneMouseMove -= GlSceneManager_SceneMouseMove;
            _rotatingMode = false;
            _translateMode = false;
        }
    }
}
